﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace FatoryTool
{
    public class PipeRender
    {
        PipeLine Pipe { get; set; }
        public PipeRender(PipeLine pipeLine)
        {
            this.Pipe = pipeLine;
        }
        static int SpAngleMin = 5;
        static int SpAngleMax = 175;
        public PathGeometry Render(System.Windows.Controls.Grid control, System.Windows.Controls.Grid tar=null)
        {
            control.Children.Clear();
            using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(new System.Drawing.Bitmap(1, 1)))
            {
                for (int i = 1; i < Pipe.Count; i++)
                {
                    if (Pipe[i].EndPoint.X == Pipe[i - 1].EndPoint.X && Pipe[i].EndPoint.Y == Pipe[i - 1].EndPoint.Y)
                    { return null; }
                    double pipeLen = CalcTools.Distance(Pipe[i].EndPoint.X, Pipe[i].EndPoint.Y, Pipe[i - 1].EndPoint.X, Pipe[i - 1].EndPoint.Y);
                    //先沿水平方向生成一个管道
                    //左上
                    Pipe[i].CalcPoints[0] = new System.Drawing.PointF((float)Pipe[i - 1].EndPoint.X, (float)(Pipe[i - 1].EndPoint.Y - Pipe.PipeDiameter / 2));
                    //右上
                    Pipe[i].CalcPoints[1] = new System.Drawing.PointF((float)(Pipe[i - 1].EndPoint.X + pipeLen), (float)(Pipe[i - 1].EndPoint.Y - Pipe.PipeDiameter / 2));
                    //左下
                    Pipe[i].CalcPoints[2] = new System.Drawing.PointF((float)Pipe[i - 1].EndPoint.X, (float)(Pipe[i - 1].EndPoint.Y + Pipe.PipeDiameter / 2));
                    //右下
                    Pipe[i].CalcPoints[3] = new System.Drawing.PointF((float)(Pipe[i - 1].EndPoint.X + pipeLen), (float)(Pipe[i - 1].EndPoint.Y + Pipe.PipeDiameter / 2));
                    
                    double pipeRotageAngle = CalcTools.Angle(new System.Windows.Point(Pipe[i - 1].EndPoint.X, Pipe[i - 1].EndPoint.Y)
                        , new System.Windows.Point(Pipe[i - 1].EndPoint.X + 100, Pipe[i - 1].EndPoint.Y)
                        , new System.Windows.Point(Pipe[i].EndPoint.X, Pipe[i].EndPoint.Y));
                    CalcTools.VectorClockDirection pipeDir = CalcTools.VectorClockDirectionCalc(new System.Windows.Point(Pipe[i - 1].EndPoint.X + 100, Pipe[i - 1].EndPoint.Y)
                        , new System.Windows.Point(Pipe[i - 1].EndPoint.X, Pipe[i - 1].EndPoint.Y)
                        , new System.Windows.Point(Pipe[i].EndPoint.X, Pipe[i].EndPoint.Y));
                    pipeRotageAngle = (pipeDir == CalcTools.VectorClockDirection.Clockwise ? pipeRotageAngle : -pipeRotageAngle);
                    //将水平管道旋转到实际的角度
                    graphics.TranslateTransform((float)Pipe[i - 1].EndPoint.X, (float)Pipe[i - 1].EndPoint.Y);
                    graphics.RotateTransform((float)pipeRotageAngle);//旋转角度
                    graphics.TranslateTransform(-(float)Pipe[i - 1].EndPoint.X, -(float)Pipe[i - 1].EndPoint.Y);
                    graphics.Transform.TransformPoints(Pipe[i].CalcPoints);
                    graphics.ResetTransform();
                }
            }

            for (int i = 1; i < Pipe.Count; i++)
            {
                if (i < Pipe.Count - 1)
                {
                    //同心圆的圆心
                    Pipe[i].Angle = CalcTools.Angle(Pipe[i].EndPoint, Pipe[i - 1].EndPoint, Pipe[i + 1].EndPoint);
                    Pipe[i].ClockDirection = CalcTools.VectorClockDirectionCalc(Pipe[i - 1].EndPoint, Pipe[i].EndPoint, Pipe[i + 1].EndPoint);
                    System.Windows.Point CircleCenterPoint = new System.Windows.Point();

                    Pipe[i].SmoothConnect = true;
                    Pipe[i].Aviable = true;
                    if (SpAngleMin < Pipe[i].Angle && Pipe[i].Angle <= SpAngleMax)
                    {
                        //管道的交点
                        System.Windows.Point Intersection1 = CalcTools.GetIntersection5_175(Pipe[i].CalcPoints[0], Pipe[i].CalcPoints[1], Pipe[i + 1].CalcPoints[0], Pipe[i + 1].CalcPoints[1]);
                        System.Windows.Point Intersection2 = CalcTools.GetIntersection5_175(Pipe[i].CalcPoints[2], Pipe[i].CalcPoints[3], Pipe[i + 1].CalcPoints[2], Pipe[i + 1].CalcPoints[3]);
                        Pipe[i].Intersection1 = Intersection1;
                        Pipe[i].Intersection2 = Intersection2;
                        //计算同心圆的圆心
                        float per = 1.5f;
                        per = per * (float)(Pipe[i].Angle / 180);

                        if (Pipe[i].ClockDirection == CalcTools.VectorClockDirection.Clockwise)
                        {
                            CircleCenterPoint.X = Intersection1.X + (Intersection1.X - Intersection2.X) * per;
                            CircleCenterPoint.Y = Intersection1.Y + (Intersection1.Y - Intersection2.Y) * per;
                        }
                        else
                        {
                            CircleCenterPoint.X = Intersection2.X + (Intersection2.X - Intersection1.X) * per;
                            CircleCenterPoint.Y = Intersection2.Y + (Intersection2.Y - Intersection1.Y) * per;
                        }
                        Pipe[i].P11 = CalcTools.LinePointProjection(Pipe[i].CalcPoints[0], Pipe[i].CalcPoints[1], CircleCenterPoint);//前一根管道
                        Pipe[i].P12 = CalcTools.LinePointProjection(Pipe[i].CalcPoints[2], Pipe[i].CalcPoints[3], CircleCenterPoint);//前一根管道
                        Pipe[i].P21 = CalcTools.LinePointProjection(Pipe[i + 1].CalcPoints[0], Pipe[i + 1].CalcPoints[1], CircleCenterPoint);//后一根管道
                        Pipe[i].P22 = CalcTools.LinePointProjection(Pipe[i + 1].CalcPoints[2], Pipe[i + 1].CalcPoints[3], CircleCenterPoint);//后一根管道
                        //管道长度不够需要延长
                        if (Pipe[i + 1].CalcPoints[0].X < Pipe[i + 1].CalcPoints[1].X && Pipe[i + 1].CalcPoints[1].X < Pipe[i].P21.X)
                        {
                            Pipe[i + 1].CalcPoints[1] = CalcTools.WinPoint2DrawPointF(Pipe[i].P21);
                            Pipe[i + 1].CalcPoints[3] = CalcTools.WinPoint2DrawPointF(Pipe[i].P22);
                            Pipe[i + 1].EndPoint = new Point(Pipe[i].P21.X + (Pipe[i].P22.X - Pipe[i].P21.X) / 2
                                , Pipe[i].P21.Y + (Pipe[i].P22.Y - Pipe[i].P21.Y) / 2);
                        }
                        else if (Pipe[i + 1].CalcPoints[0].X > Pipe[i + 1].CalcPoints[1].X && Pipe[i + 1].CalcPoints[1].X > Pipe[i].P21.X)
                        {
                            Pipe[i + 1].CalcPoints[1] = CalcTools.WinPoint2DrawPointF(Pipe[i].P21);
                            Pipe[i + 1].CalcPoints[3] = CalcTools.WinPoint2DrawPointF(Pipe[i].P22);
                            Pipe[i + 1].EndPoint = new Point(Pipe[i].P21.X + (Pipe[i].P22.X - Pipe[i].P21.X) / 2
                                , Pipe[i].P21.Y + (Pipe[i].P22.Y - Pipe[i].P21.Y) / 2);
                        }
                        //计算同心圆的半径
                        Pipe[i].Diameter1 = CalcTools.Distance(CircleCenterPoint.X, CircleCenterPoint.Y, Pipe[i].P11.X, Pipe[i].P11.Y);
                        Pipe[i].Diameter2 = CalcTools.Distance(CircleCenterPoint.X, CircleCenterPoint.Y, Pipe[i].P12.X, Pipe[i].P12.Y);
                        Pipe[i].CircleCenterPoint = new Point(CircleCenterPoint.X, CircleCenterPoint.Y);
                    }
                    else if (Pipe[i].Angle > SpAngleMax)
                    {
                        Pipe[i].Intersection1 = CalcTools.GetIntersection5_175(Pipe[i].CalcPoints[0], Pipe[i].CalcPoints[1], Pipe[i + 1].CalcPoints[0], Pipe[i + 1].CalcPoints[1]);
                        Pipe[i].Intersection2 = CalcTools.GetIntersection5_175(Pipe[i].CalcPoints[2], Pipe[i].CalcPoints[3], Pipe[i + 1].CalcPoints[2], Pipe[i + 1].CalcPoints[3]);
                        Pipe[i].SmoothConnect = false;
                    }
                    else if (Pipe[i].Angle <= SpAngleMin)
                    {
                        Pipe[i].Aviable = false;
                        return null;
                    }
                }
            }

            if (this.Pipe.Count <= 1)
            { return null; }

            PathGeometry pathGeometryF = new PathGeometry();
            PathFigure pathFigureF = new PathFigure();
            pathFigureF.StartPoint = new Point(Pipe[1].CalcPoints[0].X, Pipe[1].CalcPoints[0].Y);

            for (int i = 1; i < Pipe.Count - 1; i++)
            {
                PipeEndPoint pipeEnd = Pipe[i];
                if (pipeEnd.Aviable)
                {
                    if (pipeEnd.SmoothConnect)
                    {
                        SweepDirection dir = pipeEnd.ClockDirection == CalcTools.VectorClockDirection.CounterClockwise
                            ? SweepDirection.Clockwise
                            : SweepDirection.Counterclockwise;
                        pathFigureF.Segments.Add(new LineSegment(pipeEnd.P11, false));
                        ArcSegment arc1 = new ArcSegment(pipeEnd.P21, new Size(pipeEnd.Diameter1, pipeEnd.Diameter1), pipeEnd.Angle
                            , false, dir, false);
                        pathFigureF.Segments.Add(arc1);
                    }
                    else
                    {
                        pathFigureF.Segments.Add(new LineSegment(pipeEnd.Intersection1, false));
                    }
                }
            }
            pathFigureF.Segments.Add(new LineSegment(CalcTools.WinPoint2DrawPointF(Pipe[Pipe.Count - 1].CalcPoints[1]), false));
           
            pathFigureF.Segments.Add(new LineSegment(CalcTools.WinPoint2DrawPointF(Pipe[Pipe.Count - 1].CalcPoints[3]), false));
            for (int i = Pipe.Count - 2; i > 0; i--)
            {
                if (Pipe[i].Aviable)
                {
                    if (Pipe[i].SmoothConnect)
                    {
                        SweepDirection dir = Pipe[i].ClockDirection == CalcTools.VectorClockDirection.CounterClockwise
                            ? SweepDirection.Counterclockwise
                            : SweepDirection.Clockwise;
                        pathFigureF.Segments.Add(new LineSegment(Pipe[i].P22, false));
                        ArcSegment arc = new ArcSegment(Pipe[i].P12, new Size(Pipe[i].Diameter2, Pipe[i].Diameter2), Pipe[i].Angle
                            , false, dir, false);
                        pathFigureF.Segments.Add(arc);
                    }
                    else
                    {
                        pathFigureF.Segments.Add(new LineSegment(Pipe[i].Intersection2, false));
                    }
                }
            }
            pathFigureF.Segments.Add(new LineSegment(CalcTools.WinPoint2DrawPointF(Pipe[1].CalcPoints[2]), false));

            pathFigureF.IsClosed = true;
            pathGeometryF.Figures.Add(pathFigureF);

            return pathGeometryF;
        }

    }
}
